<template>
  <div class="device-wrapper">
    <div class="device-tip">操作提示：使用鼠标左键拖动刻度尺</div>
    <div class="device-radius">
      <img
        src="@/assets/turn-bg.png"
        :style="`transform:rotate(${-angle}deg)`"
        class="radius-img"
      />
      <div class="radius-pointer">
        <div class="pointer-line"></div>
        <div class="pointer-arrow"></div>
      </div>
    </div>
    
    <div class="device-knob" ref="knobElement">
      <div class="knob-block-box">
        <div
          class="knob-block"
          :style="`transform:translateX(${currentX}px);width:${
            nutWidth * (maxRoute + 1)
          }px;`"
          @mousedown="handleDrag"
        ></div>
      </div>
    </div>
    <div class="device-main">
      <div class="nut-box">
        <div class="nut-body"></div>
        <div class="nut-rate" :style="`left:${rateLeft}px`">
          <div class="nut-scale">
            <div
              class="nut-scale-item"
              :style="`transform: translateY(${currentX * 1.4}px);height:${
                nutWidth * (maxRoute + 1)
              }px;`"
            ></div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>
<script setup lang="ts">
import { ref, computed, watch } from "vue";

const currentX = ref(-2510); // 当前水平位移量
let startClientX = 0; // 拖动起始X坐标
let startCurrentX = 0; // 拖动起始时的currentX值
let nutWidth = 251; // 螺母宽度
const maxRoute = 50; // 最大圈数
const nutScale = ref(5); // 螺母圈数
const angle = computed(() => {
  const maxRotation = 360 * 50; // 限制最大旋转3圈
  return Math.max(
    -maxRotation,
    Math.min(maxRotation, (currentX.value / nutWidth) * 360)
  );
});
const rateLeft = computed(() => {
  return 58 + (-currentX.value / nutWidth) * 2.48;
});
const emit = defineEmits(["modelValue"]);
const realValue = ref(0); // 真实值

watch(
  () => currentX.value,
  (newVal) => {
    //保留小数点后三位数
    realValue.value = Number(Number(-newVal / nutWidth / 2).toFixed(3));
    emit("modelValue", realValue.value);
  }
);

// 新增：获取 knob 元素引用
const knobElement = ref<HTMLElement | null>(null);
let knobRect: DOMRect | null = null;
const handleDrag = (e: MouseEvent) => {
  // 更新元素位置信息（防止窗口大小变化后坐标错乱）
  knobRect = knobElement.value?.getBoundingClientRect() || null;
  startClientX = e.clientX;
  startCurrentX = currentX.value;

  const onMouseMove = (moveEvent: MouseEvent) => {
    // 新增：检查是否在控件区域内
    if (knobRect && !isInKnobArea(moveEvent)) {
      onMouseUp(); // 立即停止拖动
      return;
    }
    const deltaX = moveEvent.clientX - startClientX;
    let newX = startCurrentX + deltaX;

    // 应用边界限制
    newX = Math.max(-nutWidth * maxRoute, Math.min(newX, 0));

    currentX.value = Math.round(newX);
    nutScale.value = Math.round(currentX.value / nutWidth);
  };
  // 新增：鼠标位置验证函数
  const isInKnobArea = (e: MouseEvent) => {
    if (!knobRect) return false;
    return (
      e.clientX >= knobRect.left &&
      e.clientX <= knobRect.right &&
      e.clientY >= knobRect.top &&
      e.clientY <= knobRect.bottom
    );
  };
  const onMouseUp = () => {
    document.removeEventListener("mousemove", onMouseMove);
    document.removeEventListener("mouseup", onMouseUp);
  };

  document.addEventListener("mousemove", onMouseMove);
  document.addEventListener("mouseup", onMouseUp);
};
</script>
<style lang="less" scoped>
.device-wrapper {
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  .device-tip {
    font-family: PingFangSC-Regular;
    font-weight: 400;
    font-size: 12px;
    color: #8c8c8c;
    letter-spacing: 0;
    line-height: 16px;
  }
  .device-radius {
    height: 170px;
    width: 154px;
    position: relative;
    .radius-img {
      width: 154px;
      width: 154px;
      will-change: transform; /* 启用硬件加速 */
      /* 添加旋转中心点设置 */
      transform-origin: center center; /* 根据实际视觉调整旋转中心 */
      transition: transform 0.1s; /* 添加平滑过渡效果 */
    }
    .radius-pointer {
      position: absolute;
      bottom: 0;
      left: 50%;
      transform: translateX(-42%);
      width: 10px;
      display: flex;
      flex-direction: column;
      align-items: center;
      .pointer-line {
        width: 1px;
        height: 40px;
        background: #262626;
        margin-bottom: 1px;
        flex-shrink: 0;
      }
      .pointer-arrow {
        width: 0;
        height: 0;
        border-left: 9.5px solid transparent;

        border-right: 9.5px solid transparent;
        border-bottom: 9.5px solid #262626;
      }
    }
  }
  .device-knob {
    padding: 12px 0;
    overflow: hidden;
    width: 251px;
    margin: 0 auto;
    .knob-block-box{
      width: 100%;
      height: 20px;
      overflow: hidden;
      margin-left: -1px;
    }
    .knob-block {
      width: 12550px;
      cursor: pointer;
      will-change: transform; /* 启用硬件加速 */
      height: 20px;
      background: #f2f3f5 url(@/assets/knob-bg.png) repeat-x 128px center;
      background-size: auto 67.5%;
    }
  }
  .device-main {
    border-top: 1px solid #e6ebf1;
    width: 100%;
    padding: 13px 0;
    overflow: hidden;
    .nut-box {
      width: 100%;
      height: 100%;
      position: relative;
      .nut-body {
        background: url(@/assets/nut-body.png) no-repeat -12px center;
        height: 51px;
      }
      .nut-rate {
        width: 96px;
        height: 51px;
        background: url(@/assets/nut-rate.png) no-repeat left center;
        position: absolute;
        left: calc(100% - 96px);
        top: 0;
        .nut-scale {
          border-radius: 25px;
          overflow: hidden;
          position: absolute;
          top: 3px;
          width: 19px;
          height: 46px;
          .nut-scale-item {
            background: url(@/assets/nut-scale.png) repeat-y left 22px;
            width: 18.9px;
            background-size: 100% auto;
            height: 307px;
            transform: translateY(0px);
          }
        }
      }
    }
  }
}
</style>
